<!DOCTYPE html>
<html lang="zh-Hans">

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no">

    <link rel="stylesheet" href="./css/index.css" />
</head>

<body>
    <h1>JavaScript 作用域</h1>
    <h2>参考链接</h2>
    <ul>
        <li><a target="_blank" href="https://juejin.im/post/5c8290455188257e5d0ec64f">深入理解JavaScript作用域和作用域链</a></li>
    </ul>

    <h2>摘要</h2>

    <p>作用域，意思就是变量或者函数的有效范围。</p>

    <h3>全局作用域</h3>
    <p>全局作用域的变量或函数，可以在任何地方, 任何js文件中被访问</p>


    <h4>最外层函数和在最外层函数外面定义的变量拥有全局作用域</h4>
    <pre>
var outVariable = "我是最外层变量"; //最外层变量
function outFun() { //最外层函数
    var inVariable = "内层变量";
    function innerFun() { //内层函数
        console.log(inVariable);
    }
    innerFun();
}
console.log(outVariable); //我是最外层变量
outFun(); //内层变量
console.log(inVariable); //inVariable is not defined
innerFun(); //innerFun is not defined
    </pre>

    <h4>所有末定义直接赋值的变量自动声明为拥有全局作用域</h4>

    <pre>
function outFun2() {
    variable = "未定义直接赋值的变量";
    var inVariable2 = "内层变量2";
}
outFun2();//要先执行这个函数，否则根本不知道里面是啥
console.log(variable); //未定义直接赋值的变量
console.log(inVariable2); //inVariable2 is not defined
    </pre>

    <h4>所有window对象的属性拥有全局作用域</h4>
    <p>一般情况下，window对象的内置属性都拥有全局作用域，例如window.name、window.location、window.top等等。</p>

    <h3>函数作用域</h3>
    <p>函数作用域,是指声明在函数内部的变量，和全局作用域相反，局部作用域一般只在固定的代码片段内可访问到，最常见的例如函数内部。</p>
    <p>作用域是分层的，内层作用域可以访问外层作用域的变量，反之则不行。</p>


    <pre>
function doSomething(){
    var blogName="浪里行舟";
    function innerSay(){
        alert(blogName);
    }
    innerSay();
}
alert(blogName); //脚本错误
innerSay(); //脚本错误
    </pre>

    <h3>块级作用域</h3>
    <p>块级作用域可通过新增命令let和const声明，所声明的变量在指定块的作用域外无法被访问。（块级作用域最多被同js文件访问）</p>

    <pre>
function getValue(condition) {
    if (condition) {
        let value = "blue";
        return value;
    } else {
        // value 在此处不可用
        return null;
    }
    // value 在此处不可用
}
    </pre>
    
</body>

</html>